using System;
using System.Collections;
using System.Globalization;
using System.Text;
using Oracle.ManagedDataAccess.Client;
using OracleInternal.Common;
using OracleInternal.ConnectionPool;
using OracleInternal.I18N;
using OracleInternal.NotificationServices;

namespace OracleInternal.ServiceObjects
{
	internal class OracleHANotificationManager : OracleONSNotificationManager
	{
		private const string EvntTypeForService = "(\"eventType=database/event/service\")";

		private const string EvntTypeForHost = "(\"eventType=database/event/host\")";

		private const string PerServiceEventType = "&($'service={0}'))";

		private string m_serviceName = string.Empty;

		private Hashtable serviceNamesTable = new Hashtable();

		internal object locking = new object();

		private static DateTimeFormatInfo s_dfi;

		static OracleHANotificationManager()
		{
			s_dfi = new DateTimeFormatInfo();
			s_dfi.ShortDatePattern = "yyyy-MM-dd";
			s_dfi.ShortTimePattern = "HH:mm:ss";
		}

		internal OracleHANotificationManager()
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)262400, OracleTraceClassName.OracleHANotificationManager, OracleTraceFuncName.ctor);
			}
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)262656, OracleTraceClassName.OracleHANotificationManager, OracleTraceFuncName.ctor);
			}
		}

		protected override string GetEventTypeForNotification(string eventTypeFromDb, string serviceName)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)262400, OracleTraceClassName.OracleHANotificationManager, OracleTraceFuncName.GetEventTypeForNotification);
			}
			try
			{
				string text = "(\"eventType=database/event/service\")|(\"eventType=database/event/host\")";
				string arg = "static";
				if (!string.IsNullOrEmpty(eventTypeFromDb))
				{
					text = eventTypeFromDb.Trim();
					text = text.TrimEnd(new char[1]);
					arg = "db";
					if (!string.IsNullOrEmpty(serviceName))
					{
						if (ProviderConfig.m_bTraceLevelPrivate)
						{
							Trace.Write(OracleTraceLevel.Private, OracleTraceTag.SvcObj, OracleTraceClassName.OracleONSNotificationManager, OracleTraceFuncName.RegisterForNotification, $"(HA) (db.subscription.string={eventTypeFromDb})");
						}
						string[] array = text.Split(new char[1]
						{
							'|'
						});
						StringBuilder stringBuilder = new StringBuilder(64);
						bool flag = false;
						string[] array2 = array;
						foreach (string text2 in array2)
						{
							if (flag)
							{
								stringBuilder.Append("|");
							}
							if (text2.IndexOf("database/event/service", StringComparison.OrdinalIgnoreCase) > 0)
							{
								stringBuilder.Append("(");
								stringBuilder.Append(text2.Trim());
								stringBuilder.Append("&(%'service=" + serviceName + "'))");
							}
							else
							{
								stringBuilder.Append(text2.Trim());
							}
							flag = true;
						}
						text = stringBuilder.ToString();
						arg = "dynamic";
					}
				}
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, OracleTraceTag.SvcObj, OracleTraceClassName.OracleONSNotificationManager, OracleTraceFuncName.RegisterForNotification, $"(HA) (string.type={arg}) (subscription.string={text})");
				}
				return text;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)262656, OracleTraceClassName.OracleHANotificationManager, OracleTraceFuncName.GetEventTypeForNotification);
				}
			}
		}

		protected override void HandleEvent(object notification)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)262400, OracleTraceClassName.OracleHANotificationManager, OracleTraceFuncName.HandleEvent);
			}
			try
			{
				if (notification == null)
				{
					return;
				}
				try
				{
					byte[] array = Array.ConvertAll(((Notification)notification).body(), (sbyte a) => (byte)a);
					string text = Conv.GetInstance(871).ConvertBytesToString(array, 0, array.Length);
					if (ProviderConfig.m_bTraceLevelPrivate)
					{
						Trace.Write(OracleTraceLevel.Private, OracleTraceTag.HA, OracleTraceClassName.OracleHANotificationManager, OracleTraceFuncName.HandleEvent, text);
					}
					Hashtable hashtable = new Hashtable();
					text = text.Trim();
					string[] array2 = text.Split(' ', '\t', '=');
					for (int i = 0; i < array2.Length; i += 2)
					{
						if (array2[i] == "")
						{
							i--;
						}
						else
						{
							hashtable.Add(array2[i].ToLower(), (array2[i].ToLower() != "timestamp") ? array2[i + 1] : (array2[i + 1] + " " + array2[++i + 1]));
						}
					}
					float result = 0f;
					float.TryParse(hashtable["version"]!.ToString(), out result);
					if ((double)result >= 2.0)
					{
						return;
					}
					string text2 = ((hashtable["service"] != null) ? hashtable["service"]!.ToString()!.ToLowerInvariant() : string.Empty);
					string text3 = ((hashtable["db_domain"] != null) ? hashtable["db_domain"]!.ToString()!.ToLowerInvariant() : string.Empty);
					string text4 = ((hashtable["instance"] != null) ? hashtable["instance"]!.ToString()!.ToLowerInvariant() : string.Empty);
					string text5 = ((hashtable["database"] != null) ? hashtable["database"]!.ToString()!.ToLowerInvariant() : string.Empty);
					string text6 = ((hashtable["host"] != null) ? hashtable["host"]!.ToString()!.ToLowerInvariant() : string.Empty);
					string text7 = ((hashtable["status"] != null) ? hashtable["status"]!.ToString()!.ToLowerInvariant() : string.Empty);
					string text8 = ((hashtable["reason"] != null) ? hashtable["reason"]!.ToString()!.ToLowerInvariant() : string.Empty);
					string s = ((hashtable["timestamp"] != null) ? hashtable["timestamp"]!.ToString()!.ToLowerInvariant() : string.Empty);
					string text9 = ((hashtable["event_type"] != null) ? hashtable["event_type"]!.ToString()!.ToLowerInvariant() : string.Empty);
					string text10 = ((hashtable["timezone"] != null) ? hashtable["timezone"]!.ToString()!.ToLowerInvariant() : string.Empty);
					int num = ((hashtable["drain_timeout"] != null) ? Convert.ToInt32(hashtable["drain_timeout"]) : 0);
					lock (locking)
					{
						if (string.Equals(text9, "servicemember", StringComparison.InvariantCultureIgnoreCase))
						{
							if (!serviceNamesTable.ContainsKey(text2))
							{
								serviceNamesTable.Add(text2, num);
							}
							else
							{
								serviceNamesTable[text2] = num;
							}
						}
						if (string.Equals(text9, "service", StringComparison.InvariantCultureIgnoreCase) && string.Equals(text7, "down", StringComparison.InvariantCultureIgnoreCase) && serviceNamesTable.ContainsKey(text2))
						{
							num = Convert.ToInt32(serviceNamesTable[text2]);
							serviceNamesTable.Remove(text2);
						}
					}
					DateTime dateTime = DateTime.Parse(s, s_dfi);
					if (text10 != string.Empty)
					{
						TimeSpan offset = TimeSpan.Parse(text10.Trim(new char[1]
						{
							'+'
						}));
						dateTime = new DateTimeOffset(dateTime, offset).UtcDateTime;
					}
					OracleHAEventSource source;
					if (text9 == null || text9.Length == 0)
					{
						string text11 = ((Notification)notification).type();
						if (string.Equals(text11.Trim(), "database/event/service", StringComparison.InvariantCultureIgnoreCase))
						{
							source = ((text4 == null || text4.Length <= 0) ? OracleHAEventSource.Service : OracleHAEventSource.Instance);
							goto IL_04ab;
						}
						if (string.Equals(text11.Trim(), "database/event/host", StringComparison.InvariantCultureIgnoreCase))
						{
							source = OracleHAEventSource.Node;
							goto IL_04ab;
						}
						return;
					}
					source = (OracleHAEventSource)Enum.Parse(typeof(OracleHAEventSource), text9, ignoreCase: true);
					goto IL_04ab;
					IL_04ab:
					OracleHAEventStatus status = ((text7.ToLowerInvariant() == "up") ? OracleHAEventStatus.Up : OracleHAEventStatus.Down);
					if (ProviderConfig.m_bTraceLevelPrivate)
					{
						Trace.Write(OracleTraceLevel.Private, OracleTraceTag.HA, OracleTraceClassName.OracleHANotificationManager, OracleTraceFuncName.HandleEvent, "Event =" + source.ToString() + ";Database=" + text5 + ";Database domain=" + text3 + ";Service=" + text2 + ";Instance=" + text4 + ";Host=" + text6 + ";Status=" + status.ToString() + ";Reason=" + text8 + ";Time=" + dateTime.ToString() + ";drain_timeout=" + num + "\n");
					}
					OracleConnectionDispenser<OraclePoolManager, OraclePool, OracleConnectionImpl>.ProcessHAEvent(new OracleHAEventArgs(source, status, text2, text5, text3, text4, text6, text8, dateTime, num));
				}
				catch (Exception ex)
				{
					if (ProviderConfig.m_bTraceLevelPrivate)
					{
						Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)268697600, OracleTraceClassName.OracleHANotificationManager, OracleTraceFuncName.HandleEvent, "OracleHANotificationManager::HandleEvent() failed. -" + ex.Message);
					}
				}
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)262656, OracleTraceClassName.OracleHANotificationManager, OracleTraceFuncName.HandleEvent);
				}
			}
		}
	}
}
